package com.weayer.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sun.javafx.scene.traversal.Direction;
import com.weayer.constant.CommonStatusEnum;
import com.weayer.dto.PriceRule;
import com.weayer.dto.ResponseResult;
import com.weayer.mapper.PriceRuleMapper;
import com.weayer.remote.ServiceMapClient;
import com.weayer.request.ForecastPriceDTO;
import com.weayer.response.DirectionResponse;
import com.weayer.response.ForecastPriceResponse;
import com.weayer.util.BigDecimalUtils;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description: Service服务 - 计价 - 预估价格Service
 * @author: Weayer
 **/
@Service
@Slf4j
public class ForecastPriceService {
    @Autowired
    private ServiceMapClient serviceMapClient;
    @Autowired
    private PriceRuleMapper priceRuleMapper;

    /**
     * @Description: 预估价格
     * @Param: [depLongitude, depLatitude, desLongitude, desLatitude, cityCode, vehicleType]
     * @return: com.weayer.dto.ResponseResult
     **/
    public ResponseResult forecastPrice(String depLongitude, String depLatitude, String desLongitude, String desLatitude,
                                        String cityCode, String vehicleType){
        // 1. 调用地图服务，查询距离和时长
        ForecastPriceDTO forecastPriceDTO = new ForecastPriceDTO(
                depLongitude, depLatitude, desLongitude, desLatitude);
        ResponseResult<DirectionResponse> direction = serviceMapClient.direction(forecastPriceDTO);

        // 2. 根据距离、时长和最新计价规则，计算价格
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("city_code", cityCode);
        queryMap.put("vehicle_type", vehicleType);

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("city_code", cityCode);
        queryWrapper.eq("vehicle_type", vehicleType);
        queryWrapper.orderByDesc("fare_version");

        List<PriceRule> priceRules = priceRuleMapper.selectList(queryWrapper);
        if(priceRules.size() == 0){
            return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_EMPTY.getCode(), CommonStatusEnum.PRICE_RULE_EMPTY.getValue());
        }
        PriceRule priceRule = priceRules.get(0);
        double price = getPrice(direction.getData().getDistance(), direction.getData().getDuration(), priceRule);
        ForecastPriceResponse forecastPriceResponse = new ForecastPriceResponse();
        forecastPriceResponse.setPrice(price);
        forecastPriceResponse.setCityCode(cityCode);
        forecastPriceResponse.setVehicleType(vehicleType);
        forecastPriceResponse.setFareType(priceRule.getFareType());
        forecastPriceResponse.setFareVersion(priceRule.getFareVersion());
        return ResponseResult.success(forecastPriceResponse);
    }
    /**
     * @Description: 实际价格
     * @Param: [distance, duration, cityCode, vehicleType]
     * @return: com.weayer.dto.ResponseResult
     **/
    public ResponseResult<Double> calculatePrice(Integer distance, Integer duration, String cityCode, String vehicleType) {
        // 查询最新计价规则，计算价格
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("city_code",cityCode);
        queryWrapper.eq("vehicle_type",vehicleType);
        queryWrapper.orderByDesc("fare_version");

        List<PriceRule> priceRules = priceRuleMapper.selectList(queryWrapper);
        if (priceRules.size() == 0){
            return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_EMPTY.getCode(),CommonStatusEnum.VERIFICATION_CODE_ERROR.getValue());
        }
        PriceRule priceRule = priceRules.get(0);

        double price = getPrice(distance, duration, priceRule);
        return ResponseResult.success(price);
    }
    /**
     * @Description:   计算价格（起步价、里程费、时长费）
     * @Param: [distance, duration, priceRule]
     * @return: java.lang.Double
     **/
    public Double getPrice(Integer distance, Integer duration, PriceRule priceRule){
        double price = 0;

        // 1. 起步价
        price = BigDecimalUtils.add(price, priceRule.getStartFare());

        // 2. 里程费
        //      总里程 m -> km
        double distanceMile = BigDecimalUtils.divide(distance, 1000);
        //      起步里程
        double startMile = (double)priceRule.getStartMile();
        //      最终里程差
        double distanceSubtract = BigDecimalUtils.subtract(distanceMile, startMile);
        double mile = distanceSubtract < 0 ? 0 : distanceSubtract;
        //      里程单价
        double unitPricePerMile = priceRule.getUnitPricePerMile();
        //      计算里程费
        double mileFare = BigDecimalUtils.multiply(mile, unitPricePerMile);
        price = BigDecimalUtils.add(price, mileFare);

        // 3. 时长费
        //      时长 s -> min
        double time = BigDecimalUtils.divide(duration, 60);
        BigDecimal durationDecimal = new BigDecimal(duration);
        //      时长单价
        double unitPricePerMinute = priceRule.getUnitPricePerMinute();
        double timeFare = BigDecimalUtils.multiply(time, unitPricePerMinute);
        price = BigDecimalUtils.add(price, timeFare);

        BigDecimal priceBigDecimal = BigDecimal.valueOf(price);
        priceBigDecimal = priceBigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP);

        log.info("里程费：" + mileFare);
        log.info("时长费：" + timeFare);

        return priceBigDecimal.doubleValue();
    }

//    public static void main(String[] args) {
//        PriceRule priceRule = new PriceRule();
//        priceRule.setStartFare(10.0);
//        priceRule.setStartMile(3);
//        priceRule.setUnitPricePerMile(1.8);
//        priceRule.setUnitPricePerMinute(0.5);
//        System.out.println(getPrice(6500, 1800, priceRule));
//    }
}
